package com.omni.monitor.plugin.utils;

import com.omni.monitor.plugin.threadpool.ThreadPoolMonitor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 基于配置的线程池工具类（拒绝策略：抛弃最早的任务并记录日志）
 */
@Slf4j
@Component
public class ThreadPoolUtils {

    private final MonitorConfig.OmniThreadPool threadPoolConfig;
    private final ThreadPoolMonitor threadPoolMonitor;
    private ThreadPoolExecutor executor;

    public ThreadPoolUtils(MonitorConfig monitorConfig, ThreadPoolMonitor threadPoolMonitor) {
        this.threadPoolConfig = monitorConfig.getOmniThreadPool();
        this.threadPoolMonitor = threadPoolMonitor;
    }

    @PostConstruct
    public void init() {
        validateConfig();

        ThreadFactory threadFactory = new ThreadFactory() {
            private final AtomicInteger threadNumber = new AtomicInteger(1);
            private final String prefix = threadPoolConfig.getThreadNamePrefix() + "-thread-";

            @Override
            public Thread newThread(Runnable r) {
                Thread thread = new Thread(r, prefix + threadNumber.getAndIncrement());
                thread.setDaemon(false);
                thread.setPriority(Thread.NORM_PRIORITY);
                return thread;
            }
        };

        // 核心修改：自定义拒绝策略（继承DiscardOldestPolicy并添加日志）
        RejectedExecutionHandler rejectedHandler = new ThreadPoolExecutor.DiscardOldestPolicy() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
                // 记录被丢弃的旧任务和新提交的任务日志
                if (!e.isShutdown()) {
                    // 尝试获取队列中最旧的任务（仅为日志打印，实际已被丢弃）
                    Runnable oldestTask = e.getQueue().poll();
                    log.warn("线程池任务已满！已丢弃最早的任务，新任务将尝试提交。" +
                                    "被丢弃的旧任务：{}，新提交的任务：{}，线程池状态：{}",
                            oldestTask, r, getPoolStatus());
                    // 调用父类方法：丢弃旧任务后提交新任务
                    super.rejectedExecution(r, e);
                }
            }
        };

        // 初始化线程池（使用新的拒绝策略）
        executor = new ThreadPoolExecutor(
                threadPoolConfig.getCorePoolSize(),
                threadPoolConfig.getMaxPoolSize(),
                threadPoolConfig.getKeepAliveSeconds(),
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(threadPoolConfig.getQueueCapacity()),
                threadFactory,
                rejectedHandler // 应用自定义拒绝策略
        );
        threadPoolMonitor.register(threadPoolConfig.getThreadNamePrefix(), executor);
        log.info("线程池初始化完成！配置参数：{}，拒绝策略：DiscardOldestPolicy（丢弃最早任务）", threadPoolConfig);
    }

    // 以下方法与之前一致（参数校验、任务提交、状态查询、优雅关闭）
    private void validateConfig() {
        if (threadPoolConfig.getCorePoolSize() < 0) {
            throw new IllegalArgumentException("核心线程数（corePoolSize）不能为负数：" + threadPoolConfig.getCorePoolSize());
        }
        if (threadPoolConfig.getMaxPoolSize() <= 0 || threadPoolConfig.getMaxPoolSize() < threadPoolConfig.getCorePoolSize()) {
            throw new IllegalArgumentException("最大线程数（maxPoolSize）必须大于0且不小于核心线程数：" + threadPoolConfig.getMaxPoolSize());
        }
        if (threadPoolConfig.getKeepAliveSeconds() < 0) {
            throw new IllegalArgumentException("空闲存活时间（keepAliveSeconds）不能为负数：" + threadPoolConfig.getKeepAliveSeconds());
        }
        if (threadPoolConfig.getQueueCapacity() < 0) {
            throw new IllegalArgumentException("队列容量（queueCapacity）不能为负数：" + threadPoolConfig.getQueueCapacity());
        }
        if (threadPoolConfig.getThreadNamePrefix() == null || threadPoolConfig.getThreadNamePrefix().trim().isEmpty()) {
            throw new IllegalArgumentException("线程名称前缀（threadNamePrefix）不能为空");
        }
    }

    public void execute(Runnable task) {
        if (task == null) {
            throw new NullPointerException("提交的任务不能为null");
        }
        executor.execute(task);
    }

    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) {
            throw new NullPointerException("提交的任务不能为null");
        }
        return executor.submit(task);
    }

    public <T> Future<T> submit(Runnable task, T result) {
        if (task == null) {
            throw new NullPointerException("提交的任务不能为null");
        }
        return executor.submit(task, result);
    }

    public String getPoolStatus() {
        return String.format(
                "核心线程数=%d，活跃线程数=%d，最大线程数=%d，" +
                        "任务队列大小=%d（剩余容量=%d），已完成任务数=%d，总任务数=%d",
                executor.getCorePoolSize(),
                executor.getActiveCount(),
                executor.getMaximumPoolSize(),
                executor.getQueue().size(),
                executor.getQueue().remainingCapacity(),
                executor.getCompletedTaskCount(),
                executor.getTaskCount()
        );
    }

    @PreDestroy
    public void shutdown() {
        if (executor != null && !executor.isShutdown()) {
            log.info("开始关闭线程池... 当前状态：{}", getPoolStatus());
            executor.shutdown();
            try {
                if (!executor.awaitTermination(30, TimeUnit.SECONDS)) {
                    log.warn("线程池关闭超时，将强制终止剩余任务");
                    executor.shutdownNow();
                }
            } catch (InterruptedException e) {
                log.error("线程池关闭被中断", e);
                executor.shutdownNow();
            }
            log.info("线程池已关闭");
        }
    }

    public ThreadPoolExecutor getExecutor() {
        return executor;
    }
}